package com.grape.basic2022.base;




import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @Author pan_jin
 * @Description: $ 自定义类加载器
 * @Date: 2022/8/23 10:06
 * @Version: 1.0.0
 * @Slogan: 梦想还是要有的万一实现了呢
 */
public class MyClassLoaderTest {
    static class MyClassLoader extends ClassLoader {
        private String path;

        public MyClassLoader(String path) {
            this.path = path;
        }

        private byte[] loaderByte(String name) throws IOException {
            String s = name.replaceAll("\\.", "/");
            FileInputStream inputStream = new FileInputStream(path + "/" + name + ".class");
            int available = inputStream.available();
            byte[] bytes = new byte[available];
            inputStream.read(bytes);
            inputStream.close();
            return bytes;
        }

        protected Class<?> findClass(String name) throws ClassNotFoundException {
            try {
                byte[] bytes = loaderByte(name);
                return defineClass(name, bytes, 0, bytes.length);
            } catch (IOException e) {
                e.printStackTrace();
                throw new ClassNotFoundException();
            }
        }

        protected Class<?> loadClass(String name, boolean resolve)
                throws ClassNotFoundException {
            synchronized (getClassLoadingLock(name)) {
                // First, check if the class has already been loaded
                Class<?> c = findLoadedClass(name);
                if (c == null) {
                    long t0 = System.nanoTime();

                    if (!name.startsWith("com.grape.basic2022")) {
                        c = this.getParent().loadClass(name);
                    } else {
                        c = findClass(name);
                    }
//                    PerfCounter.getFindClassTime().addElapsedTimeFrom(t0);
//                    PerfCounter.getFindClasses().increment();
                }
                if (resolve) {
                    resolveClass(c);
                }
                return c;
            }
        }
    }

    public static void main(String[] args) throws InstantiationException {
       /* MyClassLoader myClassLoader = new MyClassLoader("D:\\workspace_test\\java_learn");
        try {
            Class<?> aClass = myClassLoader.loadClass("com.grape.basic2022.base.User");
            Object o = aClass.newInstance();
            Method method = aClass.getDeclaredMethod("sout", null);
            method.invoke(o, null);
            System.out.println("o.toString() = " + aClass.getClassLoader());

        } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }


        MyClassLoader myClassLoader2 = new MyClassLoader("D:\\workspace_test\\java_learn");
        try {
            Class<?> clazz = myClassLoader2.loadClass("com.grape.basic2022.base.User");
            Object o2 = clazz.newInstance();
            Method method2 = clazz.getDeclaredMethod("sout", null);
            method2.invoke(o2, null);
            System.out.println("o2.toString() = " + clazz.getClassLoader());

        } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }*/

    }


}
